﻿using System;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
using System.Collections.Generic;

namespace SimbaRGVMonitor.Views.Components
{
    partial class MonitorScheduleCanvas : UserControl
    {
        public MonitorScheduleCanvas()
        {
            InitializeComponent();

            zoomComputer = new ZoomComputer(this);
            InitializeSettings();
        }

        //====================================================================================================
        //以上是类型构造函数
        //----------------------------------------------------------------------------------------------------
        //以下是类型字段
        //====================================================================================================

        private Size autoScrollMinSize;
        private readonly ZoomComputer zoomComputer;
        private readonly Dictionary<string, PathItem> pathItems = new Dictionary<string, PathItem>();
        private readonly Dictionary<string, RobotItem> robotItems = new Dictionary<string, RobotItem>();
        private readonly Dictionary<string, VertexItem> vertexItems = new Dictionary<string, VertexItem>();

        //====================================================================================================
        //以上是类型字段
        //----------------------------------------------------------------------------------------------------
        //以下是类型属性
        //====================================================================================================

        public int MapTop { get; set; }
        public int MapLeft { get; set; }
        public double MapHRate { get; set; }
        public double MapVRate { get; set;  }

        public Point AutoScrollPosition
        {
            get
            {
                var x = -1 * hScrollBar.Value;
                var y = -1 * vScrollBar.Value;
                return new Point(x, y);
            }
            private set
            {
                hScrollBar.Value = Math.Max(hScrollBar.Minimum, Math.Min(hScrollBar.Maximum, value.X));
                vScrollBar.Value = Math.Max(vScrollBar.Minimum, Math.Min(vScrollBar.Maximum, value.Y));
            }
        }

        public Size AutoScrollMinSize
        {
            get { return autoScrollMinSize; }
            set
            {
                autoScrollMinSize = value;
                ResetScrollBars();
            }
        }

        //====================================================================================================
        //以上是类型属性
        //----------------------------------------------------------------------------------------------------
        //以下是初始化设置
        //====================================================================================================

        private void InitializeSettings()
        {
            InitializeRobotItems();

            hScrollBar.Visibility = Visibility.Hidden;
            vScrollBar.Visibility = Visibility.Hidden;

            canvas.Loaded += WhenCanvasLoaded;
            canvas.MouseWheel += WhenCanvasMouseWheel;
            canvas.SizeChanged += WhenCanvasSizeChanged;
        }

        private void WhenCanvasLoaded(object sender, RoutedEventArgs e)
        {
            SetScrollMinSize();
        }

        private void WhenCanvasSizeChanged(object sender, RoutedEventArgs e)
        {
            SetScrollMinSize();
        }

        private void WhenCanvasMouseWheel(object sender, MouseWheelEventArgs e)
        {
            var wheelMouse = e.GetPosition(this);
            var orginalWheelMousePosition = zoomComputer.GetZoomPosition(wheelMouse);

            if (e.Delta > 0)
            {
                zoomComputer.ZoomIn();
            }
            else
            {
                zoomComputer.ZoomOut();
            }

            var newMouseX = zoomComputer.Attach((int)orginalWheelMousePosition.X);
            var newMouseY = zoomComputer.Attach((int)orginalWheelMousePosition.Y);
            var newMousePosition = new Point(newMouseX, newMouseY);

            var currentMouseDetachPosition = zoomComputer.GetZoomPosition(wheelMouse);
            var currentMousePositionX = zoomComputer.Attach((int)currentMouseDetachPosition.X);
            var currentMousePositionY = zoomComputer.Attach((int)currentMouseDetachPosition.Y);
            var currentMousePosition = new Point(currentMousePositionX, currentMousePositionY);

            var moveX = currentMousePosition.X - newMousePosition.X;
            var moveY = currentMousePosition.Y - newMousePosition.Y;
            var x = -AutoScrollPosition.X - moveX;
            var y = -AutoScrollPosition.Y - moveY;

            AutoScrollPosition = new Point(x, y);

            Focus();
        }

        private void SetScrollMinSize()
        {
            var rectList = new List<Rect> { Rect.Empty };
            var itemRects = canvas.Children.OfType<IRectable>().Select(item => item.GetBounds()).ToArray();
            rectList.AddRange(itemRects);
            var rect = Rect.Empty;
            foreach (var current in rectList)
            {
                rect = Rect.Union(rect, current);
            }

            if(rect != Rect.Empty)
            {
                zoomComputer.SetScrollMinSize(rect);
            }
        }

        private void ResetScrollBars()
        {
            var offsetX = autoScrollMinSize.Width - canvas.ActualWidth;
            var offsetY = autoScrollMinSize.Height - canvas.ActualHeight;

            hScrollBar.Visibility = offsetX > 0 ? Visibility.Visible : Visibility.Hidden;
            vScrollBar.Visibility = offsetY > 0 ? Visibility.Visible : Visibility.Hidden;

            offsetX = Math.Max(100, offsetX);
            offsetY = Math.Max(100, offsetY);

            hScrollBar.Maximum = offsetX;
            vScrollBar.Maximum = offsetY;

            if (offsetX <= 0 && offsetY <= 0)
            {
                AutoScrollPosition = new Point(0, 0);
            }
        }
    }
}
